package loan.calc.calculator.common;

import loan.calc.dto.LoanDTO;
import loan.calc.dto.LoanRepaySegmentDTO;
import lombok.AllArgsConstructor;
import lombok.Getter;

import java.time.LocalDate;
import java.util.Comparator;
import java.util.Objects;

public class DateSelector {


    public static LocalDate obtainNextRepaymentDate(LoanDTO loan) {
        return loan.getLoanRepaySegmentList().stream()
                .filter(repaySegment -> isCurrentRepaymentSegment(loan.getBusinessDate(), repaySegment, JudgeType.NEXT_REPAYMENT_DATE))
                .map(LoanRepaySegmentDTO::getNextRepaymentDate)
                .min(Comparator.naturalOrder())
                .orElse(null);
    }

    public static LocalDate obtainLastRepaymentDate(LoanDTO loan) {
        return loan.getLoanRepaySegmentList().stream()
                .filter(repaySegment -> isCurrentRepaymentSegment(loan.getBusinessDate(), repaySegment, JudgeType.LAST_REPAYMENT_DATE))
                .map(LoanRepaySegmentDTO::getLastRepaymentDate)
                .max(Comparator.naturalOrder())
                .orElse(null);
    }

    @Getter
    @AllArgsConstructor
    private enum JudgeType {
        NEXT_REPAYMENT_DATE("判断下一个应还款日"),
        LAST_REPAYMENT_DATE("判断上一个应还款日"),
        ;
        private final String desc;
    }

    private static boolean isCurrentRepaymentSegment(LocalDate currentBusinessDate, LoanRepaySegmentDTO segment, JudgeType judgeType) {
        LocalDate segmentStartDate = segment.getSegmentStartDate();
        LocalDate segmentMaturityDate = segment.getSegmentMaturityDate();
        if (Objects.isNull(segmentStartDate) || Objects.isNull(segmentMaturityDate)) {
            return false;
        }
        if (segmentStartDate.isAfter(currentBusinessDate) || segmentMaturityDate.isBefore(currentBusinessDate)) {
            // 区段起始日期在业务日期之后 或 区段结束日期在业务日期之前
            return false;
        }
        LocalDate nextRepaymentDate = segment.getNextRepaymentDate();
        LocalDate lastRepaymentDate = segment.getLastRepaymentDate();
        switch (judgeType) {
            default:
                throw new IllegalArgumentException("无效的参数");
// 下一个还款日
            case NEXT_REPAYMENT_DATE:
                return nextRepaymentDate.isAfter(currentBusinessDate);
// 上一个还款日
            case LAST_REPAYMENT_DATE:
                return !lastRepaymentDate.isAfter(currentBusinessDate);
        }
    }
}
